package com.estun.backroundManagementService.task;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.estun.backroundManagementService.config.factoryMes.ApiCaller;
import com.estun.backroundManagementService.config.properties.ApiInfoProperties;
import com.estun.backroundManagementService.config.properties.LineInfoProperties;
import com.estun.backroundManagementService.domain.factoryMes.request.PushProductValueData;
import com.estun.backroundManagementService.domain.factoryMes.request.TestInformationRequest;
import com.estun.backroundManagementService.domain.factoryMes.request.base.BaseMesRequest;
import com.estun.backroundManagementService.domain.factoryMes.request.base.BaseMesResponse;
import com.estun.backroundManagementService.modules.product.model.ProductPassStation;
import com.estun.backroundManagementService.modules.product.service.ProductPassStationService;
import com.estun.backroundManagementService.modules.testResult.model.TestResult;
import com.estun.backroundManagementService.modules.testResult.service.TestResultService;
import com.estun.backroundManagementService.modules.workOrder.dto.WorkOrderEntity;
import com.estun.backroundManagementService.modules.workOrder.service.WorkOrderService;
import com.estun.backroundManagementService.utils.DateTimeUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Component
@AllArgsConstructor
@Profile("prd")
public class TestInformationTask {

    private final ApiCaller apiCaller;
    private final LineInfoProperties lineInfoProperties;
    private final ApiInfoProperties apiInfoProperties;
    private final WorkOrderService workOrderService;
    private final TestResultService testResultService;
    private final ProductPassStationService productPassStationService;

    /**
     * 推送 测试信息定时任务
     */
    @Scheduled(fixedRate = 30 * 1000)
    public synchronized void pushTestInformation() {
        long beginTime = System.currentTimeMillis();
        WorkOrderEntity workOrder = workOrderService.getInProcessSchedule();

        log.info("【测试线数据上报】开始任务,任务号:{}", beginTime);
        List<TestResult> toBePushList = testResultService.getToBePushed();

        if (CollectionUtils.isEmpty(toBePushList)) {
            log.warn("【测试线数据上报】本次没有数据待推送，结束任务,任务号:{}", beginTime);
            return;
        }
        int toBePushSize = toBePushList.size();
        log.info("【测试线数据上报】本次任务数量:{},任务号:{}", toBePushSize, beginTime);
        int failNumber = 0;
        //按sn分组
        Map<String, List<TestResult>> testResultMap = toBePushList.stream().collect(Collectors.groupingBy(TestResult::getProductNo));
        //遍历testResultMap
        List<PushProductValueData> pushProductValueDataList = testResultMap.entrySet()
                .stream()
                .map(entry -> buildTestResult006(entry.getKey(), entry.getValue(), workOrder))
                .collect(Collectors.toList());


        for (PushProductValueData passStationRequest : pushProductValueDataList) {
            if (passStationRequest == null) {
                log.info("【测试线数据上报】构造测试数据为空,任务号:{}", beginTime);
                continue;
            }
            BaseMesRequest<PushProductValueData> mesRequest = new BaseMesRequest<>();
            mesRequest.setData(Collections.singletonList(passStationRequest));
            BaseMesResponse mesResponse = new BaseMesResponse();
            mesResponse.setSuccess(true);
            try {
                mesResponse = apiCaller.post(apiInfoProperties.getTestInformation(), mesRequest, BaseMesResponse.class);
            } catch (Exception e) {
                log.error("【测试线数据上报】接口调用异常，记录失败,任务号:{}", beginTime);
                mesResponse = new BaseMesResponse();
                mesResponse.setSuccess(false);
                mesResponse.setFail(true);
            }
            List<Integer> idList = passStationRequest.getDataList().stream().map(PushProductValueData.PushProductValueItem::getValueId).collect(Collectors.toList());
            boolean b = testResultService.updatePushSucceed(idList,mesResponse.isSuccess());
            if (!b) {
                log.error("【测试线数据上报】更新失败，newTestResult：{}", JSON.toJSONString(idList));
            }
        }
        log.info("【测试线数据上报】任务结束,耗时:{}ms，本次任务数量：{},成功数量:{},失败数量:{},任务号:{}", System.currentTimeMillis() - beginTime, toBePushSize, toBePushSize - failNumber, failNumber, beginTime);
    }

    private PushProductValueData buildTestResult006(String sn, List<TestResult> testResultList, WorkOrderEntity workOrder) {
        PushProductValueData pushProductValueData = new PushProductValueData();
        String stationCode = lineInfoProperties.getStationCodePre() + "TE";
        pushProductValueData.setLineCode(lineInfoProperties.getLineCode());
        pushProductValueData.setMachineCode(lineInfoProperties.getLineCode().contains("5") ? "A20234065931" : "A20234078256");
        pushProductValueData.setSnNumber(sn);
        pushProductValueData.setStationCode(stationCode);
        pushProductValueData.setMaterialCode(workOrder.getMaterialCode());
        pushProductValueData.setMaterialVersion(workOrder.getMaterialVersion());

        List<PushProductValueData.PushProductValueItem> collect = testResultList.stream().map(result -> {
            PushProductValueData.PushProductValueItem pushProductValueItem = new PushProductValueData.PushProductValueItem();
            LocalDateTime date = result.getDate();
            //date转为时间戳
            pushProductValueItem.setParamTime(toShanghaiMillis(date));
            pushProductValueItem.setRealValue(result.getValue());
            pushProductValueItem.setParamName(result.getTestItem());
            pushProductValueItem.setValueId(result.getId());
            return pushProductValueItem;
        }).collect(Collectors.toList());
        pushProductValueData.setDataList(collect);
        return pushProductValueData;
    }

    /**
     * 将 LocalDateTime 转换为毫秒时间戳，使用上海时区
     *
     * @param localDateTime 要转换的 LocalDateTime 对象
     * @return 自1970-01-01T00:00:00Z以来的毫秒数
     */
    public static long toShanghaiMillis(LocalDateTime localDateTime) {
        // 使用上海时区转换 LocalDateTime 到 ZonedDateTime
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));

        // 转换 ZonedDateTime 到 Instant，然后获取毫秒时间戳
        return zonedDateTime.toInstant().toEpochMilli();
    }

    /**
     * 构造消息
     */
    private TestInformationRequest buildTestResult(TestResult testResult, WorkOrderEntity workOrder) {
        TestInformationRequest instance = new TestInformationRequest();
        // 设置各个属性的值
        instance.setFactoryCode(lineInfoProperties.getFactoryCode());
        instance.setLineCode(lineInfoProperties.getLineCode());
        String stationCode = lineInfoProperties.getStationCodePre() + "TE";
        instance.setStationCode(stationCode);
        instance.setMaterialCode(workOrder.getMaterialCode());
        instance.setMaterialVersion(workOrder.getMaterialVersion());
        String productNo = testResult.getProductNo();
        instance.setSnNumber(productNo);
        instance.setOperationCode("TE");
//        instance.setParamCode("YourParamCode");
        instance.setParamName(testResult.getTestItem());
//        instance.setStandardValue(testResult.getValue()); 无标准值
        instance.setParamRange1(testResult.getMin());
        instance.setParamRange2(testResult.getMax());
        instance.setRealValue(testResult.getValue());
        instance.setIsQualified("OK".equals(testResult.getResult()) ? 1 : 0);


        ProductPassStation productPassStation = productPassStationService.getOne(new QueryWrapper<ProductPassStation>()
                .eq("product_no", productNo)
                .eq("pass_station_id", stationCode)
                .last("limit 1"));

        if (productPassStation != null) {
            instance.setCheckStarttime(DateTimeUtils.localDateTimeToTimestamp(productPassStation.getPassStartTime()));
            instance.setCheckEndtime(DateTimeUtils.localDateTimeToTimestamp(productPassStation.getPassEndTime()));
        } else {
            instance.setCheckStarttime(DateTimeUtils.localDateTimeToTimestamp(testResult.getCreatedTime()));
            instance.setCheckEndtime(DateTimeUtils.localDateTimeToTimestamp(testResult.getCreatedTime().plusMinutes(10)));
        }

        instance.setDataStatus("0");
//        instance.setAddUserId("YourAddUserId");
        instance.setAddTime(DateTimeUtils.localDateTimeToTimestamp(testResult.getCreatedTime()));
//        instance.setEditTime(DateTimeUtils.localDateTimeToTimestamp(value.getCreateTime()));
//        instance.setEditUserId("YourEditUserId");
//        instance.setAddUserCode("YourAddUserCode");
        instance.setMachineCode(lineInfoProperties.getLineCode().contains("5") ? "A20234065931" : "A20234078256");
        return instance;
    }

}
